package com.ruoyi.common.utils;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

public class TimeUtil {

    public static Date getDateAfterDays(Date date,int days){
        Calendar calendar= new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,days);
        return calendar.getTime();
    }

    public static Date getDateStart(){
       Calendar calendar= new GregorianCalendar();
       calendar.add(Calendar.DAY_OF_MONTH,0);
       //一天的开始时间 yyyy:MM:dd 00:00:00
       calendar.set(Calendar.HOUR_OF_DAY,0);
       calendar.set(Calendar.MINUTE,0);
       calendar.set(Calendar.SECOND,0);
       calendar.set(Calendar.MILLISECOND,0);
       return calendar.getTime();
    }

    public static Date getDateEnd(){
        Calendar calendar= new GregorianCalendar();
        calendar.add(Calendar.DAY_OF_MONTH,0);
        //一天的结束时间 yyyy:MM:dd 23:59:59
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        return calendar.getTime();
    }

    public static Date getDateStart(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getDateEnd(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        //一天的结束时间 yyyy:MM:dd 23:59:59
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        return calendar.getTime();
    }

    /**
     * 判断当前时间是否在指定时段内（12：01 ~ 15：23）
     * @param times // 04:02-21:02 时间段字符串
     * @return
     */
    public static boolean compareTime(Date now,String times,SimpleDateFormat df) {
        String[] split = times.split("-");
        if (split.length < 2){
            return false;
        }
        String startStr = split[0];
        String endStr = split[1];
        String[] endStrs = endStr.split("时段");
        endStr = endStrs[0];
        try {
            Date nowTime = df.parse(df.format(now));
            Date beginTime = df.parse(startStr);
            Date endTime = df.parse(endStr);
            Calendar date = Calendar.getInstance();
            date.setTime(nowTime);

            Calendar begin = Calendar.getInstance();
            begin.setTime(beginTime);

            Calendar end = Calendar.getInstance();
            end.setTime(endTime);

            if (date.after(begin) && date.before(end)) {
                return true;
            } else {
                return false;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return true;
    }


    public static Date getTimeStartFrontDayIndex(int n,LocalDate today){
        n = n - 1;
        LocalDate futureDate = today.minusDays(n);

        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,futureDate.getYear());
        calendar.set(Calendar.MONTH,futureDate.getMonthValue() - 1);
        calendar.set(Calendar.DAY_OF_MONTH,futureDate.getDayOfMonth());

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static List<LocalDate> getTimeFrontDayListIndex(int n,LocalDate today){
        n = n - 1;
        List<LocalDate> result = new ArrayList<>();
        for (int i = n; i >= 0; i--) {
            LocalDate futureDate = today.minusDays(i);
            result.add(futureDate);
        }
        return result;
    }


    /**
     * 日期往前推n天
     * @param n 天
     * @return LocalDate
     */
    public static Date getTimeStartFrontDay(int n,LocalDate today){
        LocalDate futureDate = today.minusDays(n);

        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,futureDate.getYear());
        calendar.set(Calendar.MONTH,futureDate.getMonthValue() -1);
        calendar.set(Calendar.DAY_OF_MONTH,futureDate.getDayOfMonth());

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 日期往前推n天
     * @param n 天
     * @return LocalDate
     */
    public static Date getTimeEndFrontDay(int n,LocalDate today){
        LocalDate futureDate = today.minusDays(n);

        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,futureDate.getYear());
        calendar.set(Calendar.MONTH,futureDate.getMonthValue() - 1);
        calendar.set(Calendar.DAY_OF_MONTH,futureDate.getDayOfMonth());

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }


    /**
     * 月份往前推n月 起始时间
     * @param n 月
     * @return LocalDate
     */
    public static Date getTimeStartFrontMonth(int n,LocalDate today){
        LocalDate futureDate = today.minusMonths(n);

        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,futureDate.getYear());
        calendar.set(Calendar.MONTH,futureDate.getMonthValue());
        calendar.set(Calendar.DAY_OF_MONTH,1);

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 日期往前推n月 结束时间
     * @param n 月
     * @return LocalDate
     */
    public static Date getTimeEndFrontMonth(int n,LocalDate today){
        LocalDate futureDate = today.minusMonths(n);

        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,futureDate.getYear());
        calendar.set(Calendar.MONTH,futureDate.getMonthValue());
        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取该月的最大天数
        calendar.set(Calendar.DAY_OF_MONTH,lastDay);

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }



    /**
     * 获取指定日期开始时间
     */
    public static Date getTimeDayStart(int year,int month,int day){
        month = month - 1;
        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month);
        calendar.set(Calendar.DAY_OF_MONTH,day);

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定日期结束时间
     */
    public static Date getTimeDayEnd(int year,int month,int day){
        month = month - 1;
        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month);
        calendar.set(Calendar.DAY_OF_MONTH,day);

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 获取指定月份开始时间
     */
    public static Date getTimeMonthStart(int year,int month){
        month = month - 1;
        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month);
        calendar.set(Calendar.DAY_OF_MONTH,1);

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定月份结束时间
     */
    public static Date getTimeMonthEnd(int year,int month){
        month = month - 1;
        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month);

        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取该月的最大天数

        calendar.set(Calendar.DAY_OF_MONTH,lastDay);

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * Date 转 Calendar
     */
    public static Calendar dateToCalendar(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // int year = calendar.get(Calendar.YEAR);
       return calendar;
    }

    /**
     * Date 转 Calendar
     */
    public static Integer dateToCalendarMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH) + 1;
        return month;
    }

    public static String getDateTimeForOrder(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        return dateStr ;
    }

    /**
     * String类型的日期转换成日期，并获取这一天的起始时间
     * @param dayStr day类型时间字符
     */
    public static Date strToDateStart(String dayStr){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = formatter.parse(dayStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            return calendar.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * String类型的日期转换成日期，并获取这一天的结束时间
     * @param dayStr day类型时间字符
     */
    public static Date strToDateEnd(String dayStr){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = formatter.parse(dayStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            return calendar.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getMonthFirstDay(LocalDate.now().atStartOfDay()));
    }

    public static Date localDateTimeToDate(LocalDateTime time){
        LocalDateTime now = time;
        Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    public static Date getMonthFirstDay(LocalDateTime time){
        LocalDateTime now = time;
        LocalDateTime with = now.with(TemporalAdjusters.firstDayOfMonth());
        Instant instant = with.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    //根据month查询对应的月份时间
    public static Date getDateMonth(Integer month){

        Calendar calendar=new GregorianCalendar();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH,month);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    //根据month查询对应的对应月份第一天的时间
    public static Date getFirstDayMonth(Integer month) {
        Calendar calendar=new GregorianCalendar();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, month);
        int beginMonthMaxDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), beginMonthMaxDay, 0, 0, 0);

        return calendar.getTime();
    }


    /**
     * 当前时间加上几个自然月，每个月按照20天算
     * @param month
     * @return
     */
    public static Date getDayByMonth(Integer month) {
        Calendar calendar=new GregorianCalendar();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, month*30);
        return calendar.getTime();
    }



    /**
     * 获取指定日期上个月最后一天
     * @param date
     * @return
     */
    public static Date getEndDateOfTheLastMonth(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        Calendar cal = Calendar.getInstance();

        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);
        int lastMontMaxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), lastMontMaxDay, 0, 0, 0);

        return cal.getTime();
    }

    /**
     * 获取指定日期上个月第一天日期
     * @param date
     * @return
     */
    public static Date getBeginDateOfTheLastMonth(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-01  00:00:00");
        Calendar cal = Calendar.getInstance();

        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);
        int beginMonthMaxDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), beginMonthMaxDay, 0, 0, 0);

        return cal.getTime();
    }

    /**
     * 获取指定日期上一周第一天日期
     * @param date
     * @return
     */
    public static Date getBeginDateOfTheLastWeek(Date date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  00:00:00");
        Calendar cal = Calendar.getInstance();

        cal.setTime(date);
        int dayOfWeek =  cal.get(Calendar.DAY_OF_WEEK) - 1;

        if(dayOfWeek <= 0){
            dayOfWeek = 7;
        }
        int offset = 1 -  dayOfWeek;
        cal.add(Calendar.DATE, offset - 7);
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return cal.getTime();
    }

    /**
     * 获取指定日期上一周第一天日期
     * @param date
     * @return
     */
    public static Date getEndDateOfTheLastWeek(Date date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  00:00:00");
        Calendar cal = Calendar.getInstance();

        cal.setTime(date);
        int dayOfWeek =  cal.get(Calendar.DAY_OF_WEEK) - 1;

        if(dayOfWeek <= 0){
            dayOfWeek = 7;
        }
        int offset = 7 -  dayOfWeek;
        cal.add(Calendar.DATE, offset - 7);
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return cal.getTime();
    }

    /**
     * 判断日期是否命中日期范围
     * @param startDate
     * @param endDate
     * @param date
     * @return
     */
    public static boolean isBelongTimeSection(Date startDate, Date endDate, Date date){
        return (date.compareTo(startDate)>=0) && (endDate.compareTo(date)) >=0;
    }


    /**
     *
     * @param i 第几天
     * @param b true:查询未来日期,  false:查询过去日期
     * @return
     */
    public static Date getDays(int i, boolean b) {
        Calendar calendar = Calendar.getInstance();
        if (b) {
            calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + i);
        }else {
            calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - i);
        }
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        /**带星期的*/
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd (EEEE)");
        String result = format.format(today);
        return today;
    }

    /**
     *  指定时间加上几个间隔时间，间隔时间15或30
     * @param month
     * @param intervalDays
     * @return
     */
    public static Date getDayByIntervalDays(Integer month, Integer intervalDays, Date date) {
        Calendar calendar=new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, month*intervalDays);
        return calendar.getTime();
    }
}
